import { useUpdateEffect } from "ahooks";
import { useCallback,useState } from "react";

interface Props {
  [key: string]: any;
}
interface Options<T> {
  valuePropName?: string;

  defaultValue?: T;
  defaultValuePropName?: string;

  trigger?: string;
}

export function useControllableValue<T>(
  props: Props = {},
  options: Options<T> = {}
) {
  const {
    valuePropName = "value",
    defaultValue,
    defaultValuePropName = "defaultValue",
    trigger = "onChange",
  } = options;

  const value = props[valuePropName];

  const [state, setState] = useState<T | undefined>(() => {
    if (valuePropName in props) {
      return value;
    }

    if (defaultValuePropName in props) {
      return props[defaultValuePropName];
    }

    return defaultValue;
  });
  //相对useEffect不会在首次执行，只会在依赖更新的时候执行
  useUpdateEffect(() => {
    if (valuePropName in props) {
      setState(value);
    }
  }, [value, valuePropName]);

  //函数的缓存 props, valuePropName, trigger这三个但凡有一个有变化才会更新缓存
  const handleSetState = useCallback(
    (v: T | undefined) => {
      //组件没有绑定value值的时候
      if (!(valuePropName in props)) {
        setState(v);
      }
      //
      if (trigger in props) {
        props[trigger](v);
      }
    },
    [props, valuePropName, trigger]
  );

  return [state, handleSetState] as const;
}
